package com.example.foodtruckdemo.common;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.List;

/***
 * api执行返回结果
 * @param <T>
 */
@ApiModel(value = "API统一数据包容器对象", description = "API统一数据包容器对象")
@Data
@Accessors(chain = true)
@ToString
public class ApiResult<T> implements Serializable {

    private static final long serialVersionUID = -1414676375763798049L;

    @ApiModelProperty(value = "结果状态码,0表示调用成功，非0表示调用失败", dataType = "String")
    private String code = "0";

    @ApiModelProperty(value = "返回的消息", dataType = "String")
    private String msg = "成功";
    @ApiModelProperty(value = "总数量, 分页请求时有意义", dataType = "int")
    // 总数量,分页请求时有意义
    private long total;

    @ApiModelProperty(value = "总页数, 分页请求时有意义", dataType = "int")
    // 总页数,分页请求时有意义
    private long totalPage;

    @ApiModelProperty(value = "当前页码, 分页请求时有意义", dataType = "int")
    // 当前页码,分页请求时有意义
    private long pageNo;

    @ApiModelProperty(value = "每页条数, 分页请求时有意义", dataType = "int")
    // 每页条数,分页请求时有意义
    private long pageSize;

    @ApiModelProperty(value = "返回的具体数据对象", dataType = "object")
    //数据
    private T data;

    @ApiModelProperty(value = "是否是集合,包括数组，集合, Map", dataType = "boolean")
    //是否是集合,包括数组，集合, Map
    private boolean collectionFlag = false;

    /**
     * 隐藏消息，便于调试
     */
    @ApiModelProperty(value = "隐藏消息，便于调试", dataType = "String")
    private String hiddenMsg;

    /**
     * 业务验证失败的字段名
     */
    @ApiModelProperty(value = "业务验证失败的字段名", dataType = "String")
    private String invalidField;

    /**
     * 服务器时间戳，单位：毫秒
     */
    @ApiModelProperty(value = "服务器时间戳，单位：毫秒", dataType = "Long")
    private Long serviceTime = System.currentTimeMillis();

    public ApiResult() {
    }

    public ApiResult(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public ApiResult(String code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public ApiResult(String code, String msg, String hiddenMsg) {
        this.code = code;
        this.msg = msg;
        this.hiddenMsg = hiddenMsg;
    }

    public ApiResult(String code, String msg, String hiddenMsg, String invalidField) {
        this.code = code;
        this.msg = msg;
        this.hiddenMsg = hiddenMsg;
        this.invalidField = invalidField;
    }

    @JsonIgnore
    public boolean isSuccess() {
        return "0".equals(code);
    }

    public static <T> ApiResult<T> success(String msg) {
        return createResultVO("0", msg, null);
    }
    public static <T> ApiResult<T> success(String msg, T data) {
        return createResultVO("0", msg, data);
    }
    public static <T> ApiResult<T> success(T data) {
        return createResultVO("0", "成功", data);
    }
    public static <T> ApiResult<List<T>> success(Page<T> data) {
        ApiResult<List<T>> result = createResultVO("0", "成功", data == null ? null:data.getRecords());
        result.setPageNo(data.getCurrent());
        result.setPageSize(data.getSize());
        result.setTotal(data.getTotal());
        result.setTotalPage(data.getPages());
        return result;
    }
    public static <T> ApiResult<T> createSuccess() {
        return createResultVO("0","成功");
    }
    public static <T> ApiResult<T> createFail(String msg) {
        return createResultVO("1", msg, null);
    }
    public static <T> ApiResult<T> createFail(String code,String msg) {
        return createResultVO(code, msg, null);
    }
    public static <T> ApiResult<T> createFail(String msg, T data) {
        return createResultVO("1", msg, data);
    }
    public static <T> ApiResult<T> createFail(T data) {
        return createResultVO("1", "失败", data);
    }
    public static <T> ApiResult<T> createFail() {
        return createResultVO("1","失败");
    }
    public static <T> ApiResult<T> createResultVO(String code, String msg) {
        return createResultVO(code, msg, null);
    }

    public static <T> ApiResult<T> createResultVO(String code, String msg, T data) {
        ApiResult<T> resultVo = new ApiResult<>();
        resultVo.setCode(code);
        resultVo.setMsg(msg);
        resultVo.setData(data);
        resultVo.setServiceTime(System.currentTimeMillis());
        return resultVo;
    }
    public static void checkResult(ApiResult apiResult){
        if(apiResult != null && apiResult.isSuccess()){
            return ;
        }
        String msg = apiResult == null ? "": apiResult.msg;
        throw new BusinessException(msg);
    }
}
